#region Usings
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

using BK.SmsParsing.Exceptions;

using Lib.Sms;
#endregion

namespace BK.SmsParsing
{
    public class VabSmsBody : SmsBody
    {
        #region Readonly & Static Fields
        private readonly DateTime _paymentDateTime;
        #endregion

        #region Fields
        private decimal _amount;
        private decimal _balance;
        private string _currency;

        private string _paymentPlace;
        private readonly SmsOperation _smsOperation;
        #endregion

        protected Dictionary<SmsOperation, string> GetSmsOperationToPhraseMappings()
        {
            var result = new Dictionary<SmsOperation, string>();
            result.Add(SmsOperation.Payment, "Vy splatyly z kartky");
            result.Add(SmsOperation.PayingIn, "VI POPOVNYLY RAHUNOK ");
            result.Add(SmsOperation.Cash, "VY ZNYALY GOTIVKU Z KARTKY");
            result.Add(SmsOperation.Rejected, "vidhilena z technichih prichin");
            result.Add(SmsOperation.Percents, "Vam zarahovano");

            return result;
        }

        #region C'tors
        public VabSmsBody(string bodyContent) : base(bodyContent)
        {
            _paymentDateTime = ParsePaymentDateTime(BodyContent.Substring(25, 14));
            _smsOperation = ParseSmsOperation(BodyContent);
        }

        private SmsOperation ParseSmsOperation(string bodyContent)
        {
            Dictionary<SmsOperation, string> smsOperationToPhraseMappings = GetSmsOperationToPhraseMappings();
            SmsOperation? result = null;
            foreach (var smsOperationToPhraseMapping in smsOperationToPhraseMappings)
            {
                if (bodyContent.IndexOf(smsOperationToPhraseMapping.Value) != -1)
                {
                    if (result == null)
                    {
                        result = smsOperationToPhraseMapping.Key;
                    }
                    else
                    {
                        throw new SmsOperationAlreadyDefinedException();
                    }
                }
            }
            if (result == null)
            {
                throw new NoNullAllowedException();
            }

            return result.Value;
        }
        #endregion

        #region Instance Methods
        private DateTime ParsePaymentDateTime(string s)
        {
            string[] dateStrings = s.Substring(0, 8).Split(new[] {'.'}, StringSplitOptions.None);
            string[] timeStrings = s.Substring(9, 5).Split(new[] {':'}, StringSplitOptions.None);
            return new DateTime(int.Parse(dateStrings[2]) + 2000, int.Parse(dateStrings[1]),
                int.Parse(dateStrings[0]), int.Parse(timeStrings[0]), int.Parse(timeStrings[1]), 0);
        }
        #endregion

        #region Instance Properties
        public decimal Amount
        {
            [DebuggerStepThrough]
            get { return _amount; }
        }

        public decimal Balance
        {
            [DebuggerStepThrough]
            get { return _balance; }
        }

        public string Currency
        {
            [DebuggerStepThrough]
            get { return _currency; }
        }

        public DateTime PaymentDateTime
        {
            [DebuggerStepThrough]
            get { return _paymentDateTime; }
        }

        public string PaymentPlace
        {
            [DebuggerStepThrough]
            get { return _paymentPlace; }
        }

        public SmsOperation SmsOperation
        {
            [DebuggerStepThrough]
            get { return _smsOperation; }
        }
        #endregion
    }
}